package me.yricky.alia.ui.layoutPage

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.AcUnit
import androidx.compose.material.icons.rounded.Architecture
import androidx.compose.material.icons.rounded.BlurOn
import androidx.compose.material.icons.rounded.FilterCenterFocus
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.rememberWindowState
import me.yricky.alia.App
import me.yricky.alia.data.hierarchy.Library
import me.yricky.alia.ui.AliaIcons
import me.yricky.alia.ui.WindowInst
import me.yricky.alia.ui.component.ListWithScrollBar

/**
 * @author Yricky
 * @date 2022/1/30
 */
object LayoutPageFactory {

    fun getWindowInst(lib: Library): WindowInst {
        return object : WindowInst(){
            val viewModel: LayoutPageViewModel = LayoutPageViewModel().also {
                it.loadLib(lib)
            }

            override fun tag(): String = lib.name

            @Composable
            override fun window() {
                val currCell by viewModel.viewState.currCell.collectAsState()
                val name = "${currCell?.name}(${tag()})"
                Window(
                    state = rememberWindowState(size = DpSize(1280.dp,800.dp)),
                    title = name,
                    icon = AliaIcons.defaultWindowIcon(),
                    onCloseRequest = { App.removeWindow(this) }) {
                    Page(viewModel)
                    val dialog by viewModel.viewState.dialog.collectAsState()
                    dialog?.ComposeDialog()
                }
            }

        }
    }


    @OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
    @Composable
    fun Page(viewModel: LayoutPageViewModel){
        val lib by viewModel.viewState.lib.collectAsState()
        val cellNameFilter by viewModel.viewState.cellNameFilter.collectAsState()
        val currCell by viewModel.viewState.currCell.collectAsState()
        val canvasSessions by viewModel.viewState.canvasSessions.collectAsState()
        val canvasModel = currCell?.let {cell->
            canvasSessions.value[cell]
        }
        Row(Modifier.fillMaxSize()){
            Column(Modifier.fillMaxHeight().weight(0.25f)) {
                OutlinedTextField(
                    cellNameFilter,
                    {viewModel.setCellNameFilter(it)},
                    Modifier.fillMaxWidth().padding(4.dp,4.dp,4.dp),
                    label = { Text(App.res.value.str.filter) }
                )
                ListWithScrollBar(
                    Modifier.weight(1f)
                        .fillMaxWidth()
                ) {
                    items(lib?.cells?.filter { it.name.contains(cellNameFilter,true) } ?: emptyList()){
                        Row(
                            Modifier
                                .clickable { viewModel.setCell(it) }
                                .fillMaxWidth()
                                .padding(4.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Icon(
                                Icons.Rounded.Architecture,"",
                                tint = if(canvasSessions.value.contains(it)){
                                    MaterialTheme.colors.primary
                                }else{
                                    MaterialTheme.colors.onSurface
                                })
                            Text(it.name,Modifier.weight(1f), maxLines = 1)
                            if(currCell == it){
                                Icon(Icons.Rounded.FilterCenterFocus,"")
                            }

                        }
                    }
                }
            }

            canvasModel?.let{sessionModel->
                val invisibleLayer by sessionModel.viewState.invisibleLayer.collectAsState()
                Column(
                    Modifier.fillMaxHeight()
                    .weight(1f)
                ) {
                    Row(Modifier.padding(0.dp,4.dp,0.dp)){
                        Icon(Icons.Rounded.AcUnit,"",Modifier.size(36.dp).clickable {
                            viewModel.closeSession(currCell)
                        })
                        val showDots by sessionModel.viewState.showGridDots.collectAsState()
                        Icon(Icons.Rounded.BlurOn,"",Modifier.size(36.dp).clickable {
                            sessionModel.setShowGridDots(!showDots)
                        }, tint = if(showDots) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground)
                        Spacer(Modifier.weight(1f))
                    }
                    Surface(
                        Modifier
                            .fillMaxSize()
                            .background(MaterialTheme.colors.primary)
                            .padding(2.dp)
                    ) {
                        CellCanvas(
                            Modifier.fillMaxHeight()
                                .weight(1f),
                            sessionModel
                        )
                    }
                }
                Column(
                    Modifier.fillMaxHeight()
                        .weight(0.25f)
                ) {
                    ListWithScrollBar(Modifier.fillMaxSize()) {
                        items(sessionModel.layerRenders.sortedBy { it.layerId }){ layerRenderModel->
                            val layerStyle = layerRenderModel.style
                            val id = layerRenderModel.layerId
                            ContextMenuArea({ listOf(ContextMenuItem("Edit style") {
                                viewModel.setDialog(
                                    LayerStyleDialogInst(
                                        id,
                                        layerStyle,
                                        { ld,style -> sessionModel.setLayerStyle(ld,style) },
                                        { viewModel.setDialog(null) }
                                    )
                                )

                            }) }){
                                Row(Modifier
                                    .clickable { sessionModel.toggleLayerVisibility(id) }
                                    .padding(4.dp)
                                    .fillMaxWidth()
                                    , verticalAlignment = Alignment.CenterVertically){
                                    if(!invisibleLayer.value.contains(id)){
                                        LayerIcon(Modifier.padding(4.dp).size(24.dp),layerStyle)
                                    }
                                    Text("${id.layerId}/${id.dataTypeId}")
                                }
                            }



                        }
                    }
                }

            }
        }


    }
}